package com.joyd.joydlib.io

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import okhttp3.OkHttpClient
import okio.ByteString
import java.util.concurrent.TimeUnit

/**
 * WebSocket管理器，提供对WebSocketClient的便捷管理和使用
 */
class WebSocketManager {
    // 协程作用域
    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)

    // WebSocket客户端
    private var webSocketClient: WebSocketClient? = null

    // 配置
    private var url: String = ""
    private var clientConfig: OkHttpClient.Builder? = null

    // 事件流
    private val _messageFlow = MutableSharedFlow<String>()
    val messageFlow: SharedFlow<String> = _messageFlow.asSharedFlow()

    private val _binaryMessageFlow = MutableSharedFlow<ByteString>()
    val binaryMessageFlow: SharedFlow<ByteString> = _binaryMessageFlow.asSharedFlow()

    private val _stateFlow = MutableSharedFlow<WebSocketClient.ConnectionState>()
    val stateFlow: SharedFlow<WebSocketClient.ConnectionState> = _stateFlow.asSharedFlow()

    private val _errorFlow = MutableSharedFlow<Throwable?>()
    val errorFlow: SharedFlow<Throwable?> = _errorFlow.asSharedFlow()

    /**
     * 设置WebSocket服务器地址
     */
    fun setUrl(url: String): WebSocketManager {
        this.url = url
        return this
    }

    /**
     * 设置OkHttpClient配置
     */
    fun setClientConfig(config: OkHttpClient.Builder): WebSocketManager {
        this.clientConfig = config
        return this
    }

    /**
     * 初始化并连接WebSocket
     */
    fun connect() {
        if (url.isEmpty()) {
            throw IllegalStateException("WebSocket URL must be set before connecting")
        }

        // 如果已存在客户端，则先断开
        if (webSocketClient != null) {
            webSocketClient?.disconnect()
        }

        // 创建客户端
        val client = clientConfig?.build()
        webSocketClient = WebSocketClient(url, client)

        // 设置回调
        webSocketClient?.apply {
            setOnMessageCallback { _messageFlow.tryEmit(it) }
            setOnBinaryMessageCallback { _binaryMessageFlow.tryEmit(it) }
            setOnStateChangeCallback { _stateFlow.tryEmit(it) }
            setOnErrorCallback { _errorFlow.tryEmit(it) }

            // 连接
            connect()
        }
    }

    /**
     * 断开连接
     */
    fun disconnect() {
        webSocketClient?.disconnect()
    }

    /**
     * 暂停连接
     */
    fun pause() {
        webSocketClient?.pause()
    }

    /**
     * 恢复连接
     */
    fun resume() {
        webSocketClient?.resume()
    }

    /**
     * 发送文本消息
     */
    fun sendMessage(text: String): Boolean {
        return webSocketClient?.send(text) ?: false
    }

    /**
     * 发送二进制消息
     */
    fun sendBinaryMessage(bytes: ByteString): Boolean {
        return webSocketClient?.send(bytes) ?: false
    }

    /**
     * 设置重连配置
     */
    fun setReconnectConfig(
        maxAttempts: Int = 10,
        baseDelayMs: Long = 1000L,
        maxDelayMs: Long = 30000L
    ): WebSocketManager {
        webSocketClient?.setReconnectConfig(maxAttempts, baseDelayMs, maxDelayMs)
        return this
    }

    /**
     * 获取当前连接状态
     */
    fun getCurrentState(): WebSocketClient.ConnectionState {
        return webSocketClient?.connectionState?.value ?: WebSocketClient.ConnectionState.Disconnected
    }

    /**
     * 清理资源
     */
    fun release() {
        webSocketClient?.release()
        webSocketClient = null
        scope.cancel()
    }

    companion object {
        /**
         * 创建默认的OkHttpClient.Builder
         */
        fun createDefaultClientBuilder(): OkHttpClient.Builder {
            return OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
        }

        /**
         * 创建安全的OkHttpClient.Builder（带SSL配置）
         */
        fun createSecureClientBuilder(): OkHttpClient.Builder {
            return createDefaultClientBuilder()
            // 这里可以添加SSL配置
            // .sslSocketFactory(sslSocketFactory, trustManager)
        }
    }
}